控制反轉是一種程式設計的方式。它的精神在於程式中所需要的輔助物件,並不是在自己的類別中建立,而是由外部控制的。建立好後,將其傳遞給主程式,這個動作稱為依賴注入,是控制反轉的實現方式。
實現控制反轉的方式,Spring 的設計目標之一是為了解隅,利用依賴抽象而非依賴實例的方式,因此設計了依賴注入(DI)。
沒有使用 DI 方式,使用 New 方法來建立物件並引用
public class Notify{
private Sender sender = new Sender();
// 如果需要更換方法,每個有用到的地方都要改
// private NewSender sender = new NewSender();
public void Send() {
sender.print("Hi! I'm Sean")
}
}
將 Sender 交給 Spring 容器管理,使用 @Autowired 注入去使用,等於是透過 Spring 去建立物件出來
@Component
public class Notify{
// 如果要更改方法,往上註冊為 bean 的部分修改就可以,注入部分不需要改變
@Autowired
private Sender sender;
public void Send() {
sender.print("Hi! I'm Sean")
}
}
如果我們可能有多種 Sender 需要去實踐,可以用 interface 來建立一個介面去分成不同方法實踐
@Component
public interface Sender {
void send(String msg);
}
@Component
public class GoogleMailSender implements Sender {
@Override
public void send(String msg) {
System.out.println("內容: " + msg + " 我用 Google 郵件寄出了!!")
}
}
@Component
public class OutlookMailSender implements Sender {
@Override
public void send(String msg) {
System.out.println("內容: " + msg + " 我用 Outlook 郵件寄出了!!")
}
}
可以將 @Component 選擇注入其中一種,Spring 容器會自動幫我們選擇我們有注入的那個,但如果兩種都注入,就會出現錯誤,所以要再選擇用 @Qualifier(”bean 名稱”) 註解來指定要入住哪個
** 注意注入容器的 bean 名稱開頭是小寫
@Component
public class Notify{
@Autowired
@Qualifer("GoogleMailSender") // @Qualifer("outlookMailSender")
private Sender sender;
public void Send() {
sender.print("Hi! I'm Sean")
}
}
利用 IOC 和 DI 可以有以下優點:
class 之間的鬆耦合,降低各個 class 之間的關聯性。
像是假設我們本來得在 Notify 中去指定要使用的是哪家廠牌的 MailSender(可能是 google, yahoo...) 而這就會讓 Notify 和 MailSender 的耦合變大,但使用了 Spring IoC 之後,不需要了解這個 Sender 是哪種,只要確定有被正確注入某種可以使用的 MailSender。
交由 Spring 容器來管理這些物件的生命週期,減少不必要的引用。
因為我們將 MailSender 這個 object 改成是交由 Spring 容器來管理,因此 Spring 就會負責物件的創建、初始化、以及銷毀,所以就不需要我們親自去處理這件事情。
可以方便注入至所需要測試的程式中
所有的 object 都是由外部的 Spring 容器來做管理,因此我們就可以輕鬆在測試程式內在測試的過程中,將 Spring 容器中的 object 給替換掉,容易的使用像是 Mock 的技術。
Ref:
相關文章也會同步更新我的部落格,有興趣也可以在裡面找其他的技術分享跟資訊。